package com.myk.game.lib;

import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextWatcher;
import android.text.method.HideReturnsTransformationMethod;
import android.text.method.KeyListener;
import android.text.method.PasswordTransformationMethod;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;

import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

/**
 * 万能RecyclerView适配器
 */
public abstract class SimpleAdapter<T> extends RecyclerView.Adapter<SimpleAdapter.VH> {

    private List<T> mDatas;
    private int mLayoutId;
    private List<View> mHeaderViews;
    private OnItemClickListener<T> onItemClickListener;
    private OnItemLongClickListener<T> onItemLongClickListener;

    //获取当前视图的数据
    public final T getData(int viewPosition) {
        int dataPos = getDataPosition(viewPosition);
        return mDatas.get(dataPos);
    }

    //重新设置数据列表
    public final void setDatas(List<T> mDatas) {
        this.mDatas.clear();
        this.mDatas.addAll(mDatas);
        notifyDataSetChanged();
    }

    //添加一条数据
    public final void addData(T data, int dataPosition) {
        mDatas.add(dataPosition, data);
        int viewPosition = getViewPosition(dataPosition);
        notifyItemInserted(viewPosition);
    }

    //添加一条数据
    public final void addData(T data) {
        int newDataPosition = (mDatas.size() - 1) + 1;
        addData(data, newDataPosition);
    }

    //删除一条数据
    public final void removeData(int dataPosition) {
        mDatas.remove(dataPosition);
        int viewPosition = getViewPosition(dataPosition);
        notifyItemRemoved(viewPosition);
    }

    //删除一条数据
    public final void removeData(T data) {
        int dataPosition = mDatas.indexOf(data);
        removeData(dataPosition);
    }

    //最顶上添加一个头视图
    public final void addHeaderView(View headerView) {
        this.mHeaderViews.add(headerView);
        notifyItemInserted(mHeaderViews.size() - 1);
    }

    //设置列表项点击事件
    public final SimpleAdapter<T> setOnItemClickListener(OnItemClickListener<T> onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
        return this;
    }

    //设置列表项长按事件
    public final SimpleAdapter<T> setOnItemLongClickListener(OnItemLongClickListener<T> onItemLongClickListener) {
        this.onItemLongClickListener = onItemLongClickListener;
        return this;
    }

    //构造函数
    public SimpleAdapter(List<T> datas, @LayoutRes int layoutId) {
        this.mDatas = datas;
        this.mLayoutId = layoutId;
        this.mHeaderViews = new ArrayList<>();
    }

    /**
     * 数据绑定策略
     *
     * @param holder       当前视图
     * @param viewPosition 当前视图的位置（计算包含头布局）
     * @param data         当前数据
     * @param dataPosition 当前数据位置
     */
    public abstract void convert(VH holder, int viewPosition, T data, int dataPosition);

    /**
     * 多布局策略，返回dataPosition对应的视图
     */
    public int getLayoutId(int dataPosition) {
        return mLayoutId; //默认返回实例化时的布局
    }


    @NonNull
    @Override
    final public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        VH vh = new VH(getItemView(parent, viewType));
        return vh;
    }

    @Override
    final public void onBindViewHolder(@NonNull VH viewHolder, int viewPosition) {
        if (viewPosition <= (mHeaderViews.size() - 1)) {
            return;
        }
        else {
            final VH vh = viewHolder;
            final int vp = viewPosition;
            final int dp = getDataPosition(vp);
            final T d = mDatas.get(dp);
            convert(vh, vp, d, dp);
            if (onItemClickListener != null) {
                viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        onItemClickListener.onItemClick(vh, d, dp);
                    }
                });
            }
            if (onItemLongClickListener != null) {
                viewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View v) {
                        return onItemLongClickListener.onItemLongClick(vh, d, dp);
                    }
                });
            }
        }
    }

    @Override
    final public int getItemCount() {
        return mDatas.size() + mHeaderViews.size();
    }

    @Override
    final public int getItemViewType(int viewPosition) {
        return viewPosition;
    }

    //获取当前对应的itemView对象
    private View getItemView(ViewGroup parent, int viewType) {
        if (viewType <= (mHeaderViews.size() - 1)) { //该类型是头视图
            int headIndex = viewType;
            return mHeaderViews.get(headIndex);
        }
        else {    //该类型是数据视图
            int dataPosition = getDataPosition(viewType);
            int layoutId = getLayoutId(dataPosition);   //调用布局策略方法获取正确layoutId
            return LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
        }
    }

    //根据数据的位置获取视图的位置
    private int getViewPosition(int dataPosition) {
        return dataPosition + mHeaderViews.size();
    }

    //根据视图的位置获取数据的位置（viewPosition确保不是头布局和尾布局的位置）
    private int getDataPosition(int viewPosition) {
        return viewPosition - mHeaderViews.size();
    }

    //万能ViewHolder
    public static class VH extends RecyclerView.ViewHolder {

        private SparseArray<View> mViews;
        private KeyListener originKeyListener;
        private Drawable originBackground;
        private List<TextWatcher> originTextWatchers;

        public VH(@NonNull View itemView) {
            super(itemView);
            mViews = new SparseArray<>();
            originTextWatchers = new ArrayList<>();
        }

        public <T extends View> T getView(int id) {
            View v = mViews.get(id);
            if (v == null) {
                v = itemView.findViewById(id);
                mViews.put(id, v);
            }
            return (T) v;
        }

        public void setViewText(int id, String value) {
            TextView view = getView(id);
            view.setText(value);
        }

        public void setEditHint(int id, String text) {
            EditText view = getView(id);
            view.setHint(text);
        }

        public void setOnClickListener(int id, View.OnClickListener listener) {
            View view = getView(id);
            view.setOnClickListener(listener);
        }

        public void setEditable(int id, boolean editable) {
            EditText view = getView(id);
            /*注意之所以一定要这样写，
            是因为KeyListener是原来控件本身自带的，不是参数传进来的*/
            if (originKeyListener == null) { //只会存储一次，原来的KeyListener
                originKeyListener = view.getKeyListener();
                originBackground = view.getBackground();
            }
            if (editable) {
                view.setKeyListener(originKeyListener);
                view.setBackground(originBackground);
            }
            else {
                view.setKeyListener(null);
                view.setBackground(new ColorDrawable(Color.parseColor("#33999999")));
            }
        }

        public void addTextWatcher(int id, TextWatcher textWatcher) {
            EditText view = getView(id);
            //移除旧的watcher
            for (TextWatcher originTextWatcher : originTextWatchers) {
                view.removeTextChangedListener(originTextWatcher);
            }
            originTextWatchers.clear();
            //缓存新的watcher
            originTextWatchers.add(textWatcher);
            //添加新的watcher到控件上
            view.addTextChangedListener(textWatcher);
        }

        public void setEditCipherText(int id, boolean isCipherText) {
            EditText view = getView(id);
            if (isCipherText) {
                view.setTransformationMethod(PasswordTransformationMethod.getInstance());
            }
            else {
                view.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
            }
        }

    }

    //列表项点击事件回调接口
    public interface OnItemClickListener<T> {
        void onItemClick(VH holder, T data, int position);
    }

    //列表长按事件回调接口
    public interface OnItemLongClickListener<T> {
        boolean onItemLongClick(VH holder, T data, int position);
    }
}
